package pl.engine.ui
{
	import pl.engine.camera.Camera;
	import pl.engine.camera.ICameraIsoParams;
	import pl.engine.ui.gui.Cursor;
	import pl.engine.ui.gui.ICursor;
	import pl.error.InternalError;

	import starling.display.Stage;

	import flash.geom.Point;

	/**
	 * @author michalr
	 */
	public class UI
	{
		private static var stage:Stage;
		private static var _cursor:ICursor;
		private static var clickHandlers:Array;
		private static var mouseMoveHandlers:Array;
		private static var cursorMode:uint;
		// modes
		// ...
		public static const SELECT:uint = 0;
		public static const DRAG:uint = 1;
		// misc
		// ...
		private static var dragPoint:Point;
		private static var dragCameraPoint:Point;
		private static var cursorWasInClickedState:Boolean;

		public static function registerStage( stage:Stage ):void
		{
			UI.stage = stage;
		}

		public static function registerUIHandlers( clickHandler:Function, mouseMoveHandler:Function = null ):void
		{
			if (UI.clickHandlers == null) UI.clickHandlers = [];
			if (UI.mouseMoveHandlers == null) UI.mouseMoveHandlers = [];
			if (clickHandler != null) UI.clickHandlers.push( clickHandler );
			if (mouseMoveHandler != null) UI.mouseMoveHandlers.push( mouseMoveHandler );
		}

		public static function invokeChangeHandler( fromUI:IUI ):void
		{
			var thereIsAClick:Boolean;
			if (cursor.isReleased == true)
			{
				if (cursorWasInClickedState == true)
				{
					cursorWasInClickedState = false;
					thereIsAClick = true;
				}
			}
			else
				cursorWasInClickedState = true;

			if (UI.getCursorMode() == UI.DRAG)
			{
				if (cursor.isReleased == false)
				{
					var camera:ICameraIsoParams = Camera.iso;
					if (dragPoint == null) dragPoint = cursor.getScreenPosition().clone();
					if (dragCameraPoint == null) dragCameraPoint = new Point( camera.x, camera.y );
					var curPoint:Point = cursor.getScreenPosition();
					camera.x = dragCameraPoint.x + (dragPoint.x - curPoint.x);
					camera.y = dragCameraPoint.y + (dragPoint.y - curPoint.y);
				}
			}
			callMouseMoveHandlers();
			if (cursor.isReleased == true)
			{
				dragPoint = null;
				dragCameraPoint = null;
			}
			var i:uint;
			if (clickHandlers != null && thereIsAClick == true)
			{
				i = clickHandlers.length;
				while (i > 0)
				{
					clickHandlers[(i - 1)]();
					i--;
				}
			}
		}

		private static function callMouseMoveHandlers():void
		{
			if (mouseMoveHandlers != null)
			{
				var i:uint = mouseMoveHandlers.length;
				while (i > 0)
				{
					mouseMoveHandlers[(i - 1)]();
					i--;
				}
			}
		}

		public static function get cursor():ICursor
		{
			if (stage == null) throw new Error( InternalError.UI_STAGE_ERROR );
			if (_cursor == null) _cursor = Cursor.factory();
			return _cursor;
		}

		public static function setCursorMode( mode:uint ):void
		{
			cursorMode = mode;
			if (cursorMode == SELECT)
				cursor.setNormalCursor();
			if (cursorMode == DRAG)
				cursor.setDragCursor();
		}

		public static function getCursorMode():uint
		{
			return cursorMode;
		}
	}
}
